﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Mail;
using System.Net;

namespace CommandMail
{
    public class Client
    {
        private string _from;
        private string _to;
        private string _subject;
        private string _message;
        private bool _messageHtml;
        private string _smtpServer;
        private string _smtpUser;
        private string _smtpPassword;
        private string _configFile;
        private string _messageFile;
        private int _port = 25;
        private bool _ssl = false;

        public Client() { }

        public Client(ClientParameters parameters) {
            LoadParameters(parameters);
        }

        /// <summary>
        /// Envia el mail
        /// </summary>
        /// <returns>El estado del envío</returns>
        public ClientSendResponse Send()
        {
            ClientSendResponse response = new ClientSendResponse();

            try
            {
                var fromAddress = new MailAddress(_from);
                var toAddress = new MailAddress(_to);
                const string subject = "Test c#";
                const string body = "Body";

                using (var smtp = new SmtpClient
                {
                    Host = _smtpServer,
                    Port = _port,
                    EnableSsl = _ssl,
                    DeliveryMethod = SmtpDeliveryMethod.Network,
                    UseDefaultCredentials = _smtpUser == "",
                    Credentials = GetCredentials() //new NetworkCredential(fromAddress.Address, fromPassword)
                })
                {
                    using (var message = new MailMessage(fromAddress, toAddress) { 
                        Subject = _subject, 
                        Body = GetMessage(), 
                        IsBodyHtml = _messageHtml, 
                        BodyEncoding = Encoding.UTF8 })
                    {
                        smtp.Send(message);
                    }
                }

                response.Status = ClientSendStatus.Success;
            }
            catch (Exception ex)
            {
                response.Status = ClientSendStatus.Failed;
                response.Message = ex.InnerException == null ? ex.Message : ex.InnerException.Message;
            }

            return response;
        }

        #region PRIVATE
        /// <summary>
        /// Carga los parametros en las variables correspondientes
        /// </summary>
        /// <param name="parameters">Lista de Parametros</param>
        private void LoadParameters(ClientParameters parameters)
        {
            foreach (var item in parameters)
            {
                switch (item.Key.ToUpperInvariant())
                {
                    case "FROM":
                    case "F":
                        _from = item.Value;
                        break;
                    case "TO":
                    case "T":
                        _to = item.Value;
                        break;
                    case "SUBJECT":
                    case "S":
                        _subject = item.Value;
                        break;
                    case "MESSAGE":
                    case "M":
                        _message = item.Value;
                        break;
                    case "MESSAGETYPE":
                    case "MT":
                        _messageHtml = item.Value.ToUpper() == "HTML";
                        break;
                    case "SMTPSERVER":
                    case "SS":
                        _smtpServer = item.Value;
                        break;
                    case "SMTPUSER":
                    case "SU":
                        _smtpUser = item.Value;
                        break;
                    case "SMTPPASSWORD":
                    case "SP":
                        _smtpPassword = item.Value;
                        break;
                    case "CONFIGFILE":
                    case "CF":
                        _configFile = item.Value;
                        break;
                    case "MESSAGEFILE":
                    case "MF":
                        _messageFile = item.Value;
                        break;
                    case "SMTPPORT":
                    case "P":
                        _port = Convert.ToInt32(item.Value);
                        break;
                    case "SSL":
                        _ssl = true;
                        break;
                    default:
                        break;
                }
            }
        }

        /// <summary>
        /// Retorna el texto del mensaje.
        /// 
        /// Si se pasa un path valido en el parametro /MessageFile ó /MF, retorna el contenido del archivo,
        /// caso contrario, retorna el texto pasado en el parametro /Message ó /M
        /// </summary>
        /// <returns></returns>
        private string GetMessage()
        {
            string message = "";
            if ((_messageFile != null) && (_messageFile != "") && System.IO.File.Exists(_messageFile))
            {
                System.IO.StreamReader sr = new System.IO.StreamReader(_messageFile);
                message = sr.ReadToEnd();
            }
            else
            {
                message = _message ?? "";
            }

            return message;
        }

        /// <summary>
        /// Retorna las credenciales para conectarse al servidor de mail
        /// </summary>
        /// <returns></returns>
        private ICredentialsByHost GetCredentials()
        {
            if (_smtpUser == "")
            {
                return CredentialCache.DefaultNetworkCredentials;
            }
            else
            {
                return new NetworkCredential("ggoyeneche@gmail.com", "Baril0che");
            }
        }
        #endregion
    }

    public class ClientParameters : Dictionary<string, string>
    {
    }

    public class ClientSendResponse
    {
        public ClientSendStatus Status { get; set; }
        public string Message { get; set; }
    }

    public enum ClientSendStatus
    {
        Success,
        Failed
    }
}
